﻿//-----------------------------------------------------------------------
// <copyright company="Microsoft Corporation">
//     Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace Microsoft.DevDiv.Wpf.Samples.DeferredMarkupExtensionSample
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    using System.Windows.Threading;
    using Microsoft.DevDiv.Wpf.Samples;

    /// <summary>
    /// Interaction logic for Page1.xaml
    /// </summary>
    public partial class Page1 : Page
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "ComponentResourceKey is immutable")]
        public static readonly ResourceKey SyncImageUrlTemplateKey = new ComponentResourceKey(typeof(Page1), "SyncImageUrlTemplate");

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "ComponentResourceKey is immutable")]
        public static readonly ResourceKey AsyncImageUrlTemplateKey = new ComponentResourceKey(typeof(Page1), "AsyncImageUrlTemplate");

        public Page1()
        {
            InitializeComponent();

            this.searchTimeout = new DispatcherTimer(
                TimeSpan.FromSeconds(5),
                DispatcherPriority.Normal,
                (sender, e) => this.searchTimeout.IsEnabled = false,
                this.Dispatcher);
        }

        public IEnumerable<Uri> BingImageSearchResults
        {
            get { return this.bingImageSearchResults; }
        }

        public IEnumerable<string> BingErrorMessages
        {
            get { return this.bingErrorMessages; }
        }

        private void Handle_CanExecuteSearch(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = this.TryExecuteSearch(false);
        }

        private void Handle_ExecutedSearch(object sender, ExecutedRoutedEventArgs e)
        {
            e.Handled = this.TryExecuteSearch(true);
        }

        private bool TryExecuteSearch(bool canExecute)
        {
            bool result = false;

            if (this.queryTextBox != null && this.bingAppIdTextBox != null)
            {
                string queryText = this.queryTextBox.Text.Trim();
                string appIdText = this.bingAppIdTextBox.Text.Trim();

                if (
                    !this.searchTimeout.IsEnabled
                    && !string.IsNullOrEmpty(queryText)
                    && !string.IsNullOrEmpty(appIdText))
                {
                    if (canExecute)
                    {
                        LiveSearchService session = new LiveSearchService(appIdText);
                        LiveSearchImageSearchOptions options = new LiveSearchImageSearchOptions()
                        {
                            Query = queryText,
                            Count = 50,
                            Offset = 0
                        };

                        this.searchTimeout.IsEnabled = true;
                        this.progressBar.Visibility = Visibility.Visible;
                        session.BeginSearch(options, this.OnImageSearchCompleted);
                    }

                    result = true;
                }
            }

            return result;
        }

        private void OnImageSearchCompleted(LiveSearchResult result)
        {
            DispatcherOperationCallback callback =
                 arg =>
                 {
                     this.searchTimeout.IsEnabled = false;
                     this.progressBar.Visibility = Visibility.Collapsed;

                     // Select a template to display the image Urls
                     object resourceKey =
                         asyncImageSourceEnabledCheckbox.IsChecked.GetValueOrDefault() ?
                         AsyncImageUrlTemplateKey
                         : SyncImageUrlTemplateKey;
                     this.imageResults.ItemTemplate = this.TryFindResource(resourceKey) as DataTemplate;

                     var errorMessages =
                         from error in result.Errors
                         select error.Message;

                     this.bingErrorMessages.Clear();
                     Copy(errorMessages, this.bingErrorMessages);

                     var mediaUrls =
                         from imageResult in result.Image.Results
                         let thumbnail = imageResult.Thumbnail
                         select (thumbnail != null) ? thumbnail.Url : null;
                     this.bingImageSearchResults.Clear();
                     Copy(mediaUrls, this.bingImageSearchResults);

                     return null;
                 };

            this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, callback, null);
        }

        private static void Copy<T>(IEnumerable<T> source, ICollection<T> destination)
        {
            foreach (T item in source)
            {
                destination.Add(item);
            }
        }

        private DispatcherTimer searchTimeout;
        private ObservableCollection<Uri> bingImageSearchResults = new ObservableCollection<Uri>();
        private ObservableCollection<string> bingErrorMessages = new ObservableCollection<string>();
    }
}